package com.dm.cloud.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dm.cloud.api.dto.Account;
import com.dm.cloud.common.R;
import com.dm.cloud.dao.AccountDao;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.util.Strings;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

@CrossOrigin
@Log4j2
@RestController
@RequestMapping("test")
public class TestController {

    private final AccountDao accountDao;

    public TestController (AccountDao accountDao){
        this.accountDao = accountDao;
    }

    @PostMapping("add")
    public Mono<ResponseEntity<R>> add(@RequestBody Account account){

        int accoutn = 0;
        try {
            accoutn = accountDao.insert(account);
        }catch (Exception ex){

        }
        if(accoutn>0){
            return Mono.just(ResponseEntity.ok().body(R.success(accoutn)));
        }else{
            return Mono.just(ResponseEntity.ok().body(R.failure("10001","新增异常")));
        }
    }

    @PostMapping("update")
    public Mono<ResponseEntity<R>> update(@RequestBody Account account){
        int accoutn = 0;
        try {
            accoutn = accountDao.updateById(account);
        }catch (Exception ex){

        }
        if(accoutn>0){
            return Mono.just(ResponseEntity.ok().body(R.success(accoutn)));
        }else{
            return Mono.just(ResponseEntity.ok().body(R.failure("10001","修改异常")));
        }
    }

    @PostMapping("delete")
    public Mono<ResponseEntity<Void>> delete(@RequestBody Account account){
        int accoutn = 0;
        try {
            accoutn = accountDao.deleteById(account.getId());
        }catch (Exception ex){

        }
        if(accoutn>0){
            return Mono.just(new ResponseEntity<Void>(HttpStatus.OK));
        }else{
            return Mono.just(new ResponseEntity<Void>(HttpStatus.NOT_MODIFIED));
        }
    }

    @PostMapping("search")
    public Flux<Account> search(@RequestBody Account account){

        QueryWrapper<Account> accountQueryWrapper =new QueryWrapper<>();

        if(0!=account.getId()){
            accountQueryWrapper.eq("id",account.getId());
        }
        if(null!=account.getAmount()){
            accountQueryWrapper.eq("amount",account.getAmount());
        }
        if(Strings.isNotBlank(account.getAccountCode())){
            accountQueryWrapper.eq("account_code",account.getAccountCode());
        }
        if(Strings.isNotBlank(account.getAccountName())){
            accountQueryWrapper.eq("account_name",account.getAccountName());
        }

        List<Account> accounts = accountDao.selectList(accountQueryWrapper);

        return Flux.fromStream(accounts.stream());
    }

    @PostMapping(value = "streamsearch",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Account> streamSearch(@RequestBody Account account){

        QueryWrapper<Account> accountQueryWrapper =new QueryWrapper<>();

        if(0!=account.getId()){
            accountQueryWrapper.eq("id",account.getId());
        }
        if(null!=account.getAmount()){
            accountQueryWrapper.eq("amount",account.getAmount());
        }
        if(Strings.isNotBlank(account.getAccountCode())){
            accountQueryWrapper.eq("account_code",account.getAccountCode());
        }
        if(Strings.isNotBlank(account.getAccountName())){
            accountQueryWrapper.eq("account_name",account.getAccountName());
        }

        List<Account> accounts = accountDao.selectList(accountQueryWrapper);

        return Flux.fromStream(accounts.stream());
    }

    @GetMapping(value = "streamtest/{length}",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<Object>> streamtest(@PathVariable("length") int length){

        Flux result = Flux.fromStream(IntStream.rangeClosed(1,length+1).boxed().map(
                i->{
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                    }
                    if(i>length)
                        //最后增加一个事件信息 用来通知前端不要再重复请求后台了
                        return ServerSentEvent.<Object>builder()
                                .event("stop") //和前端addEventListener监听的事件一一对应
                                .data(-1)//ServerSentEvent必须要传data，否在前台接受不到
                                .build();
                    else
                        return String.format("测试数据%d",i);
                }
        ));

        return result;
    }

    @GetMapping(value = "testSub/{length}")
    public void testSub(@PathVariable("length") int length){
        Flux.fromStream(IntStream.rangeClosed(1,length+1)
                .boxed()
                .peek(e->log.info(e))
                .map(i->String.format("测试数据%d",i)))
                .subscribe(e->log.info(e));
    }
}
